package com.lagou.edu.homework.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @program: stage-3-module-2
 * @description:
 * @author: zhangxiaoyang
 * @date: 2020-08-23 22:36
 **/
@Component
public class GetNodeData implements Watcher, ApplicationContextAware {


    public static ZooKeeper zooKeeper;

    public static Map<String, String> dataSourceMap = new HashMap<>();

    private ApplicationContext applicationContext;


    public GetNodeData() {
    }


    public void initZK(Watcher watcher) throws IOException, InterruptedException {
        zooKeeper = new ZooKeeper(ZkConstant.ZK_SERVER + ":" + ZkConstant.ZK_PORT, 50000, watcher);
        System.out.println("消费者客户端zk连接成功！！！");
        Thread.sleep(5000);
    }

    @Override
    public void process(WatchedEvent watchedEvent) {
        if (watchedEvent.getType() == Event.EventType.NodeDataChanged) {
            try {
                List<String> children = getChildren();
                System.out.println("子节点列表：" + children);
                for (String child : children) {
                    initDB(child);
                }
                //根据zk节点数据变更，更新数据源
                try {
                    updateDB();
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            } catch (KeeperException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        if (watchedEvent.getState() == Event.KeeperState.SyncConnected) {
            try {
                List<String> children = getChildren();
                for (String child : children) {
                    //拉取并存储数据库配置信息
                    initDB(child);
                }
            } catch (KeeperException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }

    }

    private void updateDB() throws IOException, InterruptedException, SQLException {
        DataSourceConfig dataSourceConfig = applicationContext.getBean("dataSourceConfig", DataSourceConfig.class);
        DruidDataSource druidDataSource = dataSourceConfig.getDataSource();
        druidDataSource.close();
        druidDataSource = new DruidDataSource();
        druidDataSource.setDriverClassName(dataSourceMap.get("driver-class-name"));
        druidDataSource.setUrl(dataSourceMap.get("url"));
        druidDataSource.setUsername(dataSourceMap.get("username"));
        druidDataSource.setPassword(dataSourceMap.get("password"));
        dataSourceConfig.setDataSource(druidDataSource);
        druidDataSource.restart();
        initZK(this);

    }

    private List<String> getChildren() throws KeeperException, InterruptedException {
        List<String> children = zooKeeper.getChildren(ZkConstant.ROOT_NODE, true);
        System.out.println("子节点列表：" + children);
        return children;
    }

    private void initDB(String child) throws KeeperException, InterruptedException, UnsupportedEncodingException {
        byte[] bytes = zooKeeper.getData(ZkConstant.ROOT_NODE + "/" + child, true, null);
        System.out.println(ZkConstant.ROOT_NODE + "/" + child + "节点数据" + new String(bytes, "UTF-8"));
        dataSourceMap.put(child, new String(bytes, "UTF-8"));
    }


    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        if (this.applicationContext == null) {
            this.applicationContext = applicationContext;
        }
    }
}
